package com.wangjiacai.utils.ali;

import com.alibaba.nls.client.AccessToken;
import com.alibaba.nls.client.transport.ConnectionListener;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

@Slf4j
public class NettyNlsClient {

    private static final String DEFAULT_SERVER_ADDR = "wss://nls-gateway.cn-shanghai.aliyuncs.com/ws/v1";
    NettyWebSocketClient client;
    String akId;
    String akSecret;
    AccessToken accessToken;
    public int DEFAULT_CONNECTION_TIMEOUT = 5000;

    public NettyNlsClient(String url, String akId, String akSecret) {
        try {
            this.akId = akId;
            this.akSecret = akSecret;
            checkToken();
            this.client = new NettyWebSocketClient(url);
        } catch (Exception var4) {
            log.error("fail to create NlsClient", var4);
            throw new RuntimeException(var4);
        }
    }

    public NettyNlsClient(String akId, String akSecret) {
        try {
            this.akId = akId;
            this.akSecret = akSecret;
            checkToken();
            this.client = new NettyWebSocketClient(DEFAULT_SERVER_ADDR);
        } catch (Exception var3) {
            log.error("fail to create NlsClient", var3);
            throw new RuntimeException(var3);
        }
    }

    public NettyConnection connect(ConnectionListener listener) throws Exception {
        int i = 0;
        while (i < 3) {
            try {
                checkToken();
                NettyConnection nettyConnection = this.client.connect(this.accessToken.getToken(), listener, this.DEFAULT_CONNECTION_TIMEOUT);
                if (listener instanceof NettySpeechListener) {
                    NettySpeechListener nettySpeechTranscriberListener = (NettySpeechListener) listener;
                    nettySpeechTranscriberListener.setNettyConnection(nettyConnection);
                    nettyConnection.setNettySpeechTranscriberListener(nettySpeechTranscriberListener);
                }
                return nettyConnection;
            } catch (Exception e) {
                if (i == 2) {
                    log.error("failed to connect to server after 3 tries,error msg is :{}", e.getMessage());
                    throw e;
                }
                Thread.sleep(100L);
                log.warn("failed to connect to server the {} time:{} ,try again ", i, e.getMessage());
                ++i;
            }
        }
        return null;
    }

    public void shutdown() {
        this.client.shutdown();
    }

    private void checkToken() throws IOException {
        if (accessToken == null || System.currentTimeMillis() > accessToken.getExpireTime()) {
            accessToken = new AccessToken(akId, akSecret);
            accessToken.apply();
        }
    }
}
